﻿using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace GETWEBLINK
{
    internal class Program
    {
        static void Main(string[] args)
        {
            GetLinks Mission1 = new(); //实例化一个获取链接的对象
            Task.WaitAll(Task.Run(() => Mission1.Get(Mission1.SiteAddresses[0]))); //并发执行Get方法
            Thread.Sleep(3000); //主线程等待3秒钟，确保异步操作完成
        }
    }

    //为了获取某文物局网站的有关链接，可以：
    //找到含有公开的法律文件的网页地址，存储在SiteAddresses数组中
    //编写Get方法，获取网页中所有的链接
    //Get方法的实现：
    //首先找到页面中显示所有隐藏链接的按钮，从Edge浏览器的F12菜单中，元素一页观察到其类名称代码为class="morep morepmd mores1"，从右侧的事件侦听器中，可以看到click事件下绑定了若干处理函数
    //右键点击排在第一的mrep morepmd mores1，选择在源面板打开，可以在源代码页面中看到事件绑定给了一个JQuery函数
    //该函数的代码如下：
    /* $(".morepmd").click(function(){
        		var index=$(this).parent().index();
        		$(this).parent().parent().hide().siblings(".our").show().find(".our1").eq(index).show();
        	})
     */
    //
    //观察可知实际上是通过点击按钮，隐藏当前的父元素，再显示其兄弟元素our中的our1子元素，链接一直都存在于代码中，只是通过CSS样式隐藏了
    //因此可以直接获取网页源代码，然后通过正则表达式提取所有的链接
    /*
     * 需要命中的链接格式如下：
     * <div class="zfxxgk_zdgkc">
        <ul>
   
          <li><a title="中华人民共和国文物保护法（2024年修订）（英文版）" href="../../art/2025/4/30/art_2301_47356.html" target="_blank">中华人民共和国文物保护法（2024年修订）（英文版）</a><b>2025-04-30</b></li>
   
          <li><a title="中华人民共和国文物保护法（2024年修订）" href="../../art/2024/11/9/art_2301_42898.html" target="_blank">中华人民共和国文物保护法（2024年修订）</a><b>2024-11-09</b></li>
   
          <li><a title="中华人民共和国水下文物保护管理条例（2022年修订）" href="../../art/2022/2/23/art_2301_44484.html" target="_blank">中华人民共和国水下文物保护管理条例（2022年修订）</a><b>2022-02-23</b></li>
   
          <li><a title="中华人民共和国文物保护法实施条例（2017年修正本2）" href="../../art/2017/3/1/art_2301_42897.html" target="_blank">中华人民共和国文物保护法实施条例（2017年修正本2）</a><b>2017-03-01</b></li>
   
          <li><a title="博物馆条例（英文版）" href="../../art/2016/12/1/art_2301_42896.html" target="_blank">博物馆条例（英文版）</a><b>2016-12-01</b></li>
   
          <li><a title="中华人民共和国考古涉外工作管理办法" href="../../art/2016/2/6/art_2301_44485.html" target="_blank">中华人民共和国考古涉外工作管理办法</a><b>2016-02-06</b></li>
   
          <li><a title="博物馆条例" href="../../art/2015/3/2/art_2301_42895.html" target="_blank">博物馆条例</a><b>2015-03-02</b></li>
   
          <li><a title="历史文化名城名镇名村保护条例" href="../../art/2008/7/1/art_2301_44486.html" target="_blank">历史文化名城名镇名村保护条例</a><b>2008-07-01</b></li>
   
          <li><a title="中华人民共和国文物保护法(英文版)" href="../../art/2007/10/29/art_2301_42894.html" target="_blank">中华人民共和国文物保护法(英文版)</a><b>2007-10-29</b></li>
   
          <li><a title="长城保护条例" href="../../art/2007/10/28/art_2301_42893.html" target="_blank">长城保护条例</a><b>2007-10-28</b></li>
   
        </ul>
        </div>
     */

    public class GetLinks
    {
        /// <summary>
        /// 待抓取链接的网页地址数组
        /// </summary>
        public readonly string[] SiteAddresses =
        [
            "http://www.ncha.gov.cn/col/col2237/index.html?id=3",
        ];
        /// <summary>
        /// 输出文件路径
        /// </summary>
        string csvFilePath = "output.csv";

        /// <summary>
        /// 获取指定网页中的链接并保存到CSV文件中
        /// </summary>
        /// <param name="url">指定网页的url</param>
        public async void Get(string url)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    string htmlContent = await client.GetStringAsync(url);

                    // 匹配整个div的内容  
                    Regex divRegex = new Regex(@"<div class=""zfxxgk_zdgkc"">(.*?)</div>", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    MatchCollection divMatch = divRegex.Matches(htmlContent);
                    if (divMatch.Count == 0)
                    {
                        Console.WriteLine("未找到指定的div元素。");
                        return;
                    }
                    for(int i=0;i<divMatch.Count;i++)
                    {
                        string divContent = divMatch[i].Value;
                        // 匹配所有<a>标签  
                        Regex aTagRegex = new Regex(@"<a\b[^>]*>", RegexOptions.IgnoreCase);
                        MatchCollection aTags = aTagRegex.Matches(divContent);
                        //使用CodePagesEncodingProvider 解决GB18030编码问题
                        CodePagesEncodingProvider CPEP = (CodePagesEncodingProvider)CodePagesEncodingProvider.Instance;
                        Encoding.RegisterProvider(CPEP);
                        Encoding encoding = Encoding.GetEncoding("GB18030");

                        using (StreamWriter sw = new StreamWriter($"{csvFilePath}{i}", append: false, encoding))
                        {
                            sw.WriteLine("Title,Href");
                            foreach (Match aTag in aTags)
                            {
                                string aTagContent = aTag.Value;
                                // 提取href和title  
                                Regex hrefRegex = new Regex(@"href\s*=\s*[""']([^""']*)[""']", RegexOptions.IgnoreCase);
                                Regex titleRegex = new Regex(@"title\s*=\s*[""']([^""']*)[""']", RegexOptions.IgnoreCase);

                                Match hrefMatch = hrefRegex.Match(aTagContent);
                                Match titleMatch = titleRegex.Match(aTagContent);

                                if (hrefMatch.Success && titleMatch.Success)
                                {
                                    string href = hrefMatch.Groups[1].Value;
                                    string title = titleMatch.Groups[1].Value;
                                    //Console.WriteLine($"正在写入: {title}, 链接: {href}");
                                    sw.WriteLine($"{title},{"http://www.ncha.gov.cn" + href}");
                                }
                            }
                        }
                        Console.WriteLine($"数据已成功导出到 {csvFilePath}");
                    }

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发生错误: {ex.Message}");
            }
        }
    }
}
